/*
 * @Description: 
 * @Author: xuechengwu
 * @Email: xuechengwu@myhexin.com
 * @Date: 2021-11-20 14:39:51
 * @LastEditTime: 2022-02-09 15:56:32
 * @LastEditors: xuechengwu
 */
import Vue from 'vue'
import Vuex from 'vuex'
import { createPage } from '../utils/common';

Vue.use(Vuex)
const defaultPage = createPage();
const updateObject = (path, value, obj, lastObj) => {
  path.split('.').reduce((cur, key, index, array) => {
    if (index === array.length - 1) {
      if (/^\d+$/.test(key)) {
        const target = [...cur];
        target[key] = value;
        lastObj[array[index - 1]] = target;
        return lastObj;
      }
      if (cur[key] === undefined) {
        Vue.set(cur, key, value);
      } else {
        cur[key] = value;
      }
    } else if (cur[key] === undefined){
      Vue.set(cur, key, {});
    }
    lastObj = cur;
    return cur[key];
  }, obj);
}
export default new Vuex.Store({
  state: {
    version: 1.0,
    author: 'A5',
    containers: [defaultPage],
    router: [],
    values: [],
    properties: [],
    currentPage: defaultPage.mark,
    payload: '',
    layout: [8, 8, 8],
  },
  getters: {
    curPage(state) {
      return state.containers.find(vo => vo.mark === state.currentPage);
    },
    currentComponent(state) {
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      const { currentComponent, currentComponentParent } = page;
      let containers = page;
      for (let i = 0; i < currentComponentParent.length; i++) {
        const parentMark = currentComponentParent[i];
        containers = containers.components.find(vo => `${vo.mark}` === parentMark);
      }
      return containers.components.find(vo => `${vo.mark}` === `${currentComponent}`);
    }
  },
  mutations: {
    NEW_PAGE(state) {
      const { containers = [] } = state;
      const page = createPage();
      containers.push(page);
      state.currentPage = page.mark;
    },
    SWITCH_PAGE(state, data) {
      const { mark } = data;
      state.currentPage = mark;
    },
    UPDATE_PAGE(state, data) {
      const { mark, changes = [] } = data;
      const pageIndex = state.containers.findIndex(vo => `${vo.mark}` === `${mark}`);
      console.log('page index===>', pageIndex);
      if (pageIndex >= 0) {
        const page = state.containers[pageIndex];
        changes.forEach((vo) => {
          const { path, value } = vo;
          updateObject(path, value, page, page);
        })
      }
    },
    SWITCH_COMPONENT(state, data) {
      const { parents, mark } = data;
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      if (page) {
        page.currentComponent = mark;
        page.currentComponentParent = parents;
      }
    },
    SORT_COMPONENT(state, data) {
      const { oldIndex, newIndex } = data;
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      if (page) {
        const { components = [] } = page;
        components.splice(newIndex, 0, components.splice(oldIndex, 1)[0]);
        const newComponents = components.splice(0);
        page.components = newComponents;
      }
    },
    SET_PAYLOAD(state, data) {
      state.payload = data;
    },
    REMOVE_COMPONENT(state) {
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      if (page) {
        let container = page;
        const { currentComponentParent, currentComponent } = page;
        // 先查找到目标的容器组件
        for(let i = 0; i < currentComponentParent.length; i++) {
          const mark = currentComponentParent[i];
          const component = container.components.find(vo => `${vo.mark}` === `${mark}`);
          container = component;
        }
        const componentIndex = container.components.findIndex(vo => `${vo.mark}` === `${currentComponent}`);
        if (componentIndex >= 0) {
          container.components.splice(componentIndex, 1);
          page.currentComponent = '';
          page.currentComponentParent = [];
        }
      }
    },
    UNSELECT_COMPONENT(state) {
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      if (page) {
        page.currentComponent = '';
        page.currentComponentParent = [];
      }
    },
    ADD_COMPONENT(state, payload) {
      const { parent = [], components = [], name, data, style, isContainer, links, mark = new Date().getTime() } = payload;
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      if (page) {
        let container = page;
        // 先查找到目标的容器组件
        for(let i = 0; i < parent.length; i++) {
          const mark = parent[i];
          const component = container.components.find(vo => `${vo.mark}` === `${mark}`);
          container = component;
        }
        if (!container.components) {
          Vue.set(container, 'components', []);
        }
        container.components.push({
          mark,
          name,
          data,
          style: Object.assign({}, style),
          isContainer,
          links,
          components,
        });
        console.log('container===>', container);
      }
    },
    UPDATE_COMPONENT(state, payload) {
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      if (page) {
        const { currentComponent, currentComponentParent } = page;
        let container = page;
        for (let i = 0; i < currentComponentParent.length; i++) {
          const parentMark = currentComponentParent[i];
          container = container.components.find(vo => `${vo.mark}` === `${parentMark}`);
        }
        const component = container.components.find(vo => `${vo.mark}` === currentComponent);
        const { changes = [] } = payload;
        changes.forEach((vo) => {
          const { path, value } = vo;
          updateObject(path, value, component, component);
        })
      }
    },

    ADD_INTERFACE(state, payload) {
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      if (page) {
        const { interfaces = [], values = {} } = page;
        const { api, key, data, name, params } = payload;
        const interfaceIndex = interfaces.findIndex(vo => vo.key === key);
        if (interfaceIndex >= 0) {
          interfaces.splice(interfaceIndex, 1);
        }
        interfaces.push({ key, api, name, params });
        values[key] = data;
      }
    },
    /**
     * 移除接口
     * @param {*}} state 
     * @param {*} payload 
     */
    REMOVE_INTERFACE(state, payload) {
      const { mark } = payload;
      const page = state.containers.find(vo => vo.mark === mark);
      if (page) {
        const { interfaces = [], values = {} } = page;
        const { key } = payload;
        const interfaceIndex = interfaces.findIndex(vo => vo.key === key);
        if (interfaceIndex >= 0) {
          interfaces.splice(interfaceIndex, 1);
        }
        Vue.delete(values, key);
      }
    },

    UPDATE_LINK(state, payload) {
      const page = state.containers.find(vo => vo.mark === state.currentPage);
      if (page) {
        const { currentComponent, currentComponentParent } = page;
        let container = page;
        for (let i = 0; i < currentComponentParent.length; i++) {
          const parentMark = currentComponentParent[i];
          container = container.components.find(vo => `${vo.mark}` === `${parentMark}`);
        }
        const component = container.components.find(vo => `${vo.mark}` === currentComponent);
        const { selectedKey, source, path, type = 0 } = payload;
        const { links = [] } = component;
        const linkIndex = links.findIndex(vo => vo.path === path);
        if (linkIndex >= 0) {
          links.splice(linkIndex, 1);
        }
        links.push({
          selectedKey,
          source,
          path,
          type,
        });
      }
    },
    SET_LAYOUT(state, data) {
      const { layout, payload } = data;
      state.layout = layout;
      state.payload = payload;
    },
    /**
     * 新增页面数据
     * @param {*} state 
     * @param {*} data 
     */
    ADD_PAGE_DATA(state, payload) {
      const { mark, data = {} } = payload;
      const page = state.containers.find(vo => vo.mark === mark);
      if (page) {
        const { datas = {} } = page;
        if (datas[data.key]) {
          datas[data.key] = data;
        } else {
          Vue.set(datas, data.key, data);
        }
      }
    },
    /**
     * 删除页面数据
     * @param {*} state 
     * @param {*} payload 
     */
    REMOVE_PAGE_DATA(state, payload) {
      const { mark, data = {} } = payload;
      const page = state.containers.find(vo => vo.mark === mark);
      if (page) {
        const { datas = {} } = page;
        Vue.delete(datas, data.key);
      }
    }

  },
  actions: {
  },
  modules: {
  }
})
